﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Media.Effects;

namespace D3crft.Windows.UserControls {

    public partial class ucCharacterChooser : UserControl {
        public event Characters.ClassObjects.ocCharacter.CharacterEventHandler evNewCharacterPressed;
        public event Characters.ClassObjects.ocCharacter.CharacterEventHandler evCharacterSelected;
        public event Characters.ClassObjects.ocCharacter.CharacterEventHandler evCharacterDeleted;

        Grid oRootGrid;

        List<string> lCharacterIDs;
        List<string> lCharacterNames;
        List<Characters.ClassObjects.ocCharacter.eCharacterClass> lCharacterClasses;
        List<Border> lCharacterAvatarBorders;
        List<Border> lCharacterNameBorders;
        List<Label> lCharacterNameLabels;
        List<Label> lCharacterClassLabels;
        List<UserControl> lCharacterNameUCs;
        List<Image> lCharacterNameCloseButtons;

        Border oAddNew_Border;
        Label oAddNew_Label;
        UserControl oAddNew_UserControl;


        int iCharacterCount = 0;
        int iHoveredIndex = -2;
        int iSelectedIndex = -2;
        int iPressedIndex = -2;

        bool bMouseDown = false;

        // ####################################################
        // #####    Class Initialization
        // ####################################################
        #region Class Initialization

        public ucCharacterChooser() {
            InitializeComponent();
            do_Initialize();
            do_Preset();
        }

        private void do_Initialize() {
            lCharacterIDs = new List<string>();
            lCharacterNames = new List<string>();
            lCharacterClasses = new List<Characters.ClassObjects.ocCharacter.eCharacterClass>();
            lCharacterAvatarBorders = new List<Border>();
            lCharacterNameBorders = new List<Border>();
            lCharacterNameLabels = new List<Label>();
            lCharacterClassLabels = new List<Label>();
            lCharacterNameUCs = new List<UserControl>();
            lCharacterNameCloseButtons = new List<Image>();
        }

        private void do_Preset() {
            oRootGrid = (FindName("RootGrid") as Grid);

            this.Loaded += new RoutedEventHandler(ev_Object_Loaded);
        }

        #endregion

        // ####################################################
        // #####    Private Functions
        // ####################################################
        #region Private Functions

        private bool get_IsIDAlreadyListed(string sID) {
            for (int i = 0; i < iCharacterCount; i++) {
                if (sID == lCharacterIDs[i]) { return true; }
            }
            return false;
        }

        private int get_IndexByCharID(string sID) {
            for (int i = 0; i < iCharacterCount; i++) {
                if (lCharacterIDs[i] == sID) {
                    return i;
                }
            }
            return -1;
        }

        private int get_IndexByUserControl(UserControl oUserControl) {
            int iIndex;
            if (oUserControl.Name != "Control_A") {
                int.TryParse(oUserControl.Name.Split('_')[1], out iIndex);
                return iIndex;
            }
            else {
                return -1;
            }
        }

        private int get_IndexByCloseButton(Image oCloseButton) {
            int iIndex;
            int.TryParse(oCloseButton.Name.Split('_')[1], out iIndex);
            return iIndex;
        }

        private void do_ApplyDefaultColorByIndex(int iIndex) {
            if (iIndex == -1) {
                oAddNew_Border.Background = (Brush)FindResource("Brush_DefaultBackground");
                oAddNew_Label.Foreground = (Brush)FindResource("Brush_DefaultForeground");
            }
            else {
                lCharacterAvatarBorders[iIndex].Background = (Brush)FindResource("Brush_DefaultBackground");
                lCharacterNameBorders[iIndex].Background = (Brush)FindResource("Brush_DefaultBackground");
                lCharacterNameLabels[iIndex].Foreground = (Brush)FindResource("Brush_DefaultForeground");
                lCharacterClassLabels[iIndex].Foreground = (Brush)FindResource("Brush_DefaultForeground");
            }
        }

        private void do_ApplyHighlightedColorByIndex(int iIndex) {
            if (iIndex == -1) {
                oAddNew_Border.Background = Application.Current.FindResource("Gradient_HighlightedUC") as Brush;
                oAddNew_Border.BorderBrush = Application.Current.FindResource("Brush_HighlightedBorder") as Brush;
                oAddNew_Label.Foreground = Application.Current.FindResource("Brush_DefaultForeground") as Brush;
            }
            else {
                lCharacterAvatarBorders[iIndex].Background = Application.Current.FindResource("Gradient_HighlightedUC") as Brush;
                lCharacterAvatarBorders[iIndex].BorderBrush = Application.Current.FindResource("Brush_HighlightedBorder") as Brush;
                lCharacterNameBorders[iIndex].Background = Application.Current.FindResource("Gradient_HighlightedUC") as Brush;
                lCharacterNameBorders[iIndex].BorderBrush = Application.Current.FindResource("Brush_HighlightedBorder") as Brush;
                lCharacterNameLabels[iIndex].Foreground = Application.Current.FindResource("Brush_DefaultForeground") as Brush;
                lCharacterClassLabels[iIndex].Foreground = Application.Current.FindResource("Brush_DefaultForeground") as Brush;
            }
        }

        private void do_ApplyPressedColorByIndex(int iIndex) {
            if (iIndex == -1) {
                oAddNew_Border.Background = (Brush)FindResource("Gradient_PressedUC");
                oAddNew_Border.BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                oAddNew_Label.Foreground = (Brush)FindResource("Brush_PressedForeground");
            }
            else {
                lCharacterAvatarBorders[iIndex].Background = (Brush)FindResource("Gradient_PressedUC");
                lCharacterAvatarBorders[iIndex].BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                lCharacterNameBorders[iIndex].Background = (Brush)FindResource("Gradient_PressedUC");
                lCharacterNameBorders[iIndex].BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                lCharacterNameLabels[iIndex].Foreground = (Brush)FindResource("Brush_PressedForeground");
                lCharacterClassLabels[iIndex].Foreground = (Brush)FindResource("Brush_PressedForeground");
            }
        }

        private void do_ApplySelectedColorByIndex(int iIndex) {
            if (iIndex == -1) {
                oAddNew_Border.Background = (Brush)FindResource("Gradient_SelectedUC");
                oAddNew_Border.BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                oAddNew_Label.Foreground = (Brush)FindResource("Brush_PressedForeground");
            }
            else {
                lCharacterAvatarBorders[iIndex].Background = (Brush)FindResource("Gradient_SelectedUC");
                lCharacterAvatarBorders[iIndex].BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                lCharacterNameBorders[iIndex].Background = (Brush)FindResource("Gradient_SelectedUC");
                lCharacterNameBorders[iIndex].BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                lCharacterNameLabels[iIndex].Foreground = (Brush)FindResource("Brush_PressedForeground");
                lCharacterClassLabels[iIndex].Foreground = (Brush)FindResource("Brush_PressedForeground");
            }
        }

        private void do_ReOrderPlates() {
            for (int i = 0; i < iCharacterCount; i++) {
                lCharacterAvatarBorders[i].Margin = new Thickness(10.0, 10.0 + (i * (10.0 + 40.0)), 0, 0);
                lCharacterNameBorders[i].Margin = new Thickness(60.0, 10.0 + (i * (10.0 + 40.0)), 0, 0);

                lCharacterAvatarBorders[i].Name = "AvatarBorder_" + i.ToString();

                lCharacterNameBorders[i].Name = "NameBorder_" + i.ToString();

                lCharacterNameLabels[i].Name = "Label_" + i.ToString();

                lCharacterClassLabels[i].Name = "LabelC_" + i.ToString();

                lCharacterNameUCs[i].Name = "Control_" + i.ToString();

                lCharacterNameCloseButtons[i].Name = "Close_" + i.ToString();
            }

            do_RePositionAddButton();
        }

        private void do_CreateAddButton() {
            DropShadowEffect oEffect;
            Grid oGrid;
            Image oImage;

            oAddNew_Border = new Border();
            oAddNew_Border.Name = "Border_A";
            oAddNew_Border.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            oAddNew_Border.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            oAddNew_Border.Margin = new Thickness(60.0, 10.0 + (iCharacterCount * (10.0 + 40.0)), 0, 0);
            oAddNew_Border.Width = 150;
            oAddNew_Border.Height = 33;
            oAddNew_Border.Background = Brushes.White;
            oAddNew_Border.BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
            oAddNew_Border.BorderThickness = new Thickness(1.0);
            oAddNew_Border.CornerRadius = new CornerRadius(3.0);

            oEffect = new DropShadowEffect();
            oEffect.Color = Color.FromArgb(255, 0, 0, 0);
            oEffect.Direction = 315;
            oEffect.ShadowDepth = 2;
            oEffect.BlurRadius = 5;
            oEffect.Opacity = 0.3;

            oGrid = new Grid();
            oGrid.Margin = new Thickness(0.0);

            oAddNew_Label = new Label();
            oAddNew_Label.Name = "Label_A";
            oAddNew_Label.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            oAddNew_Label.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            oAddNew_Label.Margin = new Thickness(58, 3, 0, 0);
            oAddNew_Label.Foreground = Application.Current.FindResource("Brush_DefaultForeground") as Brush;
            oAddNew_Label.FontSize = 13;
            oAddNew_Label.Content = "Add New";

            oAddNew_UserControl = new UserControl();
            oAddNew_UserControl.Name = "Control_A";
            oAddNew_UserControl.Margin = new Thickness(0.0);
            oAddNew_UserControl.Background = Brushes.Transparent;
            oAddNew_UserControl.MouseDown += new MouseButtonEventHandler(ev_Plates_MouseDown);
            oAddNew_UserControl.MouseUp += new MouseButtonEventHandler(ev_Plates_MouseUp);
            oAddNew_UserControl.MouseEnter += new MouseEventHandler(ev_Plates_MouseEnter);
            oAddNew_UserControl.MouseLeave += new MouseEventHandler(ev_Plates_MouseLeave);

            oImage = new Image();
            oImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            oImage.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            oImage.Margin = new Thickness(32.0, 5.0, 0.0, 0.0);
            oImage.Width = 22;
            oImage.Height = 22;
            oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/icon_characterchooser_addnew_22.png", UriKind.Absolute));

            oGrid.Children.Add(oImage);
            oGrid.Children.Add(oAddNew_Label);
            oGrid.Children.Add(oAddNew_UserControl);
            oAddNew_Border.Effect = oEffect;
            oAddNew_Border.Child = oGrid;
            oRootGrid.Children.Add(oAddNew_Border);
        }

        private void do_RePositionAddButton() {
            oAddNew_Border.Margin = new Thickness(60.0, 10.0 + (iCharacterCount * (10.0 + 40.0)), 0.0, 0.0);
        }

        private void ev_Plates_MouseDown(object sender, EventArgs ea) {
            int iIndex = get_IndexByUserControl((UserControl)sender);

            bMouseDown = true;
            if (iIndex > -1) {
                if (iPressedIndex > -1) {
                    do_ApplyDefaultColorByIndex(iPressedIndex);
                }
                iPressedIndex = iIndex;
            }
            do_ApplyPressedColorByIndex(iIndex);
        }

        private void ev_Plates_MouseUp(object sender, EventArgs ea) {
            int iIndex = get_IndexByUserControl((UserControl)sender);

            bMouseDown = false;
            if (iIndex == -1) {
                // new char
                do_ApplyHighlightedColorByIndex(iIndex);
                if (evNewCharacterPressed != null) evNewCharacterPressed(this, new Characters.ClassObjects.CharacterEventArgs());
            } else {
                do_ApplySelectedColorByIndex(iIndex);
                iPressedIndex = -2;
                if (iSelectedIndex != iIndex) {
                    if (iSelectedIndex > -1) {
                        do_ApplyDefaultColorByIndex(iSelectedIndex);
                    }
                    iSelectedIndex = iIndex;
                    // click
                    if (evCharacterSelected != null) evCharacterSelected(this, new Characters.ClassObjects.CharacterEventArgs { sCharacterID = lCharacterIDs[iIndex], eCharacterClass = lCharacterClasses[iIndex], sCharacterName = lCharacterNames[iIndex], oCharacter = null });
                }
            }


        }

        private void ev_Plates_MouseEnter(object sender, EventArgs ea) {
            int iIndex = get_IndexByUserControl((UserControl)sender);

            if (iHoveredIndex == iIndex) {
                // mark icon from hovered to normal
                // stay visible
            }
            else {
                if (iHoveredIndex > -1) {
                    // delete old visibility
                    lCharacterNameCloseButtons[iHoveredIndex].Visibility = System.Windows.Visibility.Hidden;
                }
                // create new visibility
                iHoveredIndex = iIndex;
                if (iIndex > -1) lCharacterNameCloseButtons[iHoveredIndex].Visibility = System.Windows.Visibility.Visible;
            }
            if (iSelectedIndex != iIndex) {
                do_ApplyHighlightedColorByIndex(iIndex);
            }
        }

        private void ev_Plates_MouseLeave(object sender, EventArgs ea) {
            int iIndex = get_IndexByUserControl((UserControl)sender);

            if (bMouseDown) {
                bMouseDown = false;
                iPressedIndex = -2;
            }

            if (iIndex > -1) {
                if (!lCharacterNameCloseButtons[iIndex].IsMouseOver) {
                    lCharacterNameCloseButtons[iIndex].Visibility = System.Windows.Visibility.Hidden;
                    iHoveredIndex = -2;
                    if (iSelectedIndex != iIndex) {
                        do_ApplyDefaultColorByIndex(iIndex);
                    }
                }
            }
            else if (iIndex == -1) {
                iHoveredIndex = -2;
                if (iSelectedIndex != iIndex) {
                    do_ApplyDefaultColorByIndex(iIndex);
                }
            }




        }

        private void ev_Close_MouseDown(object sender, EventArgs ea) {
            int iIndex = get_IndexByCloseButton((Image)sender);


            // mark as pressed
        }

        private void ev_Close_MouseUp(object sender, EventArgs ea) {
            int iIndex = get_IndexByCloseButton((Image)sender);

            if (MessageBox.Show("Are you sure you want to delete the character '" + lCharacterNames[iIndex] + "'?", "D3Crft", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) {
                // delete
                iHoveredIndex = -1;
                if (evCharacterDeleted != null) evCharacterDeleted(this, new Characters.ClassObjects.CharacterEventArgs{ sCharacterID = lCharacterIDs[iIndex], eCharacterClass = lCharacterClasses[iIndex], sCharacterName = lCharacterNames[iIndex], oCharacter = null });
                RemoveCharacter(lCharacterIDs[iIndex]);
            }
        }

        private void ev_Close_MouseEnter(object sender, EventArgs ea) {
            int iIndex = get_IndexByCloseButton((Image)sender);

        }

        private void ev_Close_MouseLeave(object sender, EventArgs ea) {
            int iIndex = get_IndexByCloseButton((Image)sender);

        }

        private void ev_Object_Loaded(object sender, EventArgs ea) {
            if (IsLoaded) {
                if (oRootGrid.Children.Count == 0) {
                    oRootGrid.Children.Clear();
                    do_CreateAddButton();
                }
            }
        }
        
        #endregion

        // ####################################################
        // #####    Public Access
        // ####################################################
        #region Public Access

        public int GetCharacterCount() {
            return iCharacterCount;
        }

        public string GetSelectedCharacterID() {
            if (iSelectedIndex > -1) {
                return lCharacterIDs[iSelectedIndex];
            }
            else { return null; }
        }

        public string GetSelectedCharacterName() {
            if (iSelectedIndex > -1) {
                return lCharacterNames[iSelectedIndex];
            }
            else { return null; }
        }

        public Characters.ClassObjects.ocCharacter.eCharacterClass GetSelectedCharacterClass() {
            if (iSelectedIndex > -1) {
                return lCharacterClasses[iSelectedIndex];
            }
            else { return Characters.ClassObjects.ocCharacter.eCharacterClass.Unknown; }
        }

        public void SelectCharacter(string sID) {
            int iIndex = get_IndexByCharID(sID);
            if (iIndex > -1) {
                if (iSelectedIndex != iIndex) {
                    if (iSelectedIndex > -1) {
                        // restore
                        do_ApplyDefaultColorByIndex(iSelectedIndex);
                    }
                    iSelectedIndex = iIndex;
                    do_ApplySelectedColorByIndex(iSelectedIndex);
                    // click
                    if (evCharacterSelected != null) evCharacterSelected(this, new D3crft.Characters.ClassObjects.CharacterEventArgs { sCharacterID = lCharacterIDs[iIndex], eCharacterClass = lCharacterClasses[iIndex], sCharacterName = lCharacterNames[iIndex], oCharacter = null });
                }
            }
        }

        public void AddCharacter(string sID, string sName, Characters.ClassObjects.ocCharacter.eCharacterClass eClass) {
            if (!get_IsIDAlreadyListed(sID)) {
                UserControl oUserControl;
                Border oBorder;
                Image oImage;
                Label oLabel;
                Label oLabelClass;
                Grid oGrid;
                DropShadowEffect oEffect;

                oBorder = new Border();
                oBorder.Name = "AvatarBorder_" + iCharacterCount.ToString();
                oBorder.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                oBorder.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                oBorder.Margin = new Thickness(10.0, 10.0 + (iCharacterCount * (10.0 + 40.0)), 0, 0);
                oBorder.Width = 40;
                oBorder.Height = 40;
                oBorder.Background = Brushes.White;
                oBorder.BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                oBorder.BorderThickness = new Thickness(1.0);
                oBorder.CornerRadius = new CornerRadius(3.0);

                oEffect = new DropShadowEffect();
                oEffect.Color = Color.FromArgb(255, 0, 0, 0);
                oEffect.Direction = 315;
                oEffect.ShadowDepth = 2;
                oEffect.BlurRadius = 5;
                oEffect.Opacity = 0.3;

                oImage = new Image();
                oImage.Margin = new Thickness(0.0);
                switch (eClass) {
                    case Characters.ClassObjects.ocCharacter.eCharacterClass.Barbarian:
                        oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/avatar_barbarian_transparent_40.png", UriKind.Absolute));
                        break;
                    case Characters.ClassObjects.ocCharacter.eCharacterClass.Crusader:
                        oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/avatar_crusader_transparent_40.png", UriKind.Absolute));
                        break;
                    case Characters.ClassObjects.ocCharacter.eCharacterClass.Demon_Hunter:
                        oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/avatar_demonhunter_transparent_40.png", UriKind.Absolute));
                        break;
                    case Characters.ClassObjects.ocCharacter.eCharacterClass.Monk:
                        oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/avatar_monk_transparent_40.png", UriKind.Absolute));
                        break;
                    case Characters.ClassObjects.ocCharacter.eCharacterClass.Witch_Doctor:
                        oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/avatar_witchdoctor_transparent_40.png", UriKind.Absolute));
                        break;
                    case Characters.ClassObjects.ocCharacter.eCharacterClass.Wizard:
                        oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/avatar_wizard_transparent_40.png", UriKind.Absolute));
                        break;
                    default:

                        break;
                }

                oBorder.Effect = oEffect;
                oBorder.Child = oImage;
                oRootGrid.Children.Add(oBorder);
                lCharacterAvatarBorders.Add(oBorder);

                // 2

                oBorder = new Border();
                oBorder.Name = "NameBorder_" + iCharacterCount.ToString();
                oBorder.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                oBorder.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                oBorder.Margin = new Thickness(60.0, 10.0 + (iCharacterCount * (10.0 + 40.0)), 0, 0);
                oBorder.Width = 150;
                oBorder.Height = 40;
                oBorder.Background = Brushes.White;
                oBorder.BorderBrush = Application.Current.FindResource("Brush_Border") as Brush;
                oBorder.BorderThickness = new Thickness(1.0);
                oBorder.CornerRadius = new CornerRadius(3.0);

                oEffect = new DropShadowEffect();
                oEffect.Color = Color.FromArgb(255, 0, 0, 0);
                oEffect.Direction = 315;
                oEffect.ShadowDepth = 2;
                oEffect.BlurRadius = 5;
                oEffect.Opacity = 0.3;

                oGrid = new Grid();
                oGrid.Margin = new Thickness(0.0);

                oLabel = new Label();
                oLabel.Name = "Label_" + iCharacterCount.ToString();
                oLabel.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
                oLabel.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                oLabel.Margin = new Thickness(0.0);
                oLabel.Height = 26.0;
                oLabel.Foreground = Application.Current.FindResource("Brush_DefaultForeground") as Brush;
                oLabel.Background = Brushes.Transparent;
                oLabel.FontSize = 14;
                oLabel.Content = sName;

                oLabelClass = new Label();
                oLabelClass.Name = "LabelC_" + iCharacterCount.ToString();
                oLabelClass.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
                oLabelClass.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                oLabelClass.Margin = new Thickness(0.0, 18.0, -2.0, 0.0);
                oLabelClass.Height = 22.0;
                oLabelClass.Foreground = Application.Current.FindResource("Brush_DefaultForeground") as Brush;
                oLabelClass.Background = Brushes.Transparent;
                oLabelClass.FontSize = 11;
                oLabelClass.FontStyle = FontStyles.Italic;
                oLabelClass.Content = Characters.ClassObjects.ocCharacter.GetClassString(eClass);

                oUserControl = new UserControl();
                oUserControl.Name = "Control_" + iCharacterCount.ToString();
                oUserControl.Margin = new Thickness(0.0);
                oUserControl.Background = Brushes.Transparent;
                oUserControl.MouseDown += new MouseButtonEventHandler(ev_Plates_MouseDown);
                oUserControl.MouseUp += new MouseButtonEventHandler(ev_Plates_MouseUp);
                oUserControl.MouseEnter += new MouseEventHandler(ev_Plates_MouseEnter);
                oUserControl.MouseLeave += new MouseEventHandler(ev_Plates_MouseLeave);

                oImage = new Image();
                oImage.Name = "Close_" + iCharacterCount.ToString();
                oImage.Width = 10;
                oImage.Height = 10;
                oImage.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
                oImage.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                oImage.Margin = new Thickness(0.0, 3.0, 3.0, 0.0);
                oImage.Source = new BitmapImage(new Uri("pack://application:,,,/D3Crft;component/images/icon_characterchooser_close_normal.png", UriKind.Absolute));
                oImage.MouseDown += new MouseButtonEventHandler(ev_Close_MouseDown);
                oImage.MouseUp += new MouseButtonEventHandler(ev_Close_MouseUp);
                oImage.MouseEnter += new MouseEventHandler(ev_Close_MouseEnter);
                oImage.MouseLeave += new MouseEventHandler(ev_Close_MouseLeave);
                oImage.Visibility = System.Windows.Visibility.Hidden;

                oGrid.Children.Add(oLabel);
                oGrid.Children.Add(oLabelClass);
                oGrid.Children.Add(oUserControl);
                oGrid.Children.Add(oImage);
                oBorder.Effect = oEffect;
                oBorder.Child = oGrid;
                oRootGrid.Children.Add(oBorder);
                lCharacterNameBorders.Add(oBorder);
                lCharacterNameLabels.Add(oLabel);
                lCharacterClassLabels.Add(oLabelClass);
                lCharacterNameUCs.Add(oUserControl);
                lCharacterNameCloseButtons.Add(oImage);

                lCharacterIDs.Add(sID);
                lCharacterNames.Add(sName);
                lCharacterClasses.Add(eClass);
                iCharacterCount++;

                do_RePositionAddButton();
            }
        }

        public void RemoveCharacter(string sID) {
            if (get_IsIDAlreadyListed(sID)) {
                int iIndex = get_IndexByCharID(sID);

                if (iIndex > -1) {
                    if (iHoveredIndex > -1) { lCharacterNameCloseButtons[iHoveredIndex].Visibility = System.Windows.Visibility.Hidden; do_ApplyDefaultColorByIndex(iHoveredIndex); }
                    iHoveredIndex = -2;
                    //if (iSelectedIndex == iIndex) { iSelectedIndex = -1; }
                    //if (iPressedIndex > -1) do_ApplyDefaultColorByIndex(iPressedIndex);
                    if (iPressedIndex > -1) { iPressedIndex = -2; do_ApplyDefaultColorByIndex(iPressedIndex); }
                    if (iSelectedIndex == iIndex) { iSelectedIndex = -2; }
                    iPressedIndex = -2;
                    bMouseDown = false;

                    // remove char
                    oRootGrid.Children.Remove(lCharacterAvatarBorders[iIndex]);
                    oRootGrid.Children.Remove(lCharacterNameBorders[iIndex]);
                    lCharacterIDs.RemoveAt(iIndex);
                    lCharacterNames.RemoveAt(iIndex);
                    lCharacterClasses.RemoveAt(iIndex);
                    lCharacterAvatarBorders.RemoveAt(iIndex);
                    lCharacterNameBorders.RemoveAt(iIndex);
                    lCharacterNameLabels.RemoveAt(iIndex);
                    lCharacterClassLabels.RemoveAt(iIndex);
                    lCharacterNameUCs.RemoveAt(iIndex);
                    lCharacterNameCloseButtons.RemoveAt(iIndex);
                    iCharacterCount--;

                    // reorder
                    do_ReOrderPlates();
                }
            }
        }

        public void ClearCharacters() {
            bMouseDown = false;
            iHoveredIndex = -2;
            iSelectedIndex = -2;
            iPressedIndex = -2;
            oRootGrid.Children.Clear();
            lCharacterIDs.Clear();
            lCharacterNames.Clear();
            lCharacterClasses.Clear();
            lCharacterAvatarBorders.Clear();
            lCharacterNameBorders.Clear();
            lCharacterNameLabels.Clear();
            lCharacterClassLabels.Clear();
            lCharacterNameUCs.Clear();
            lCharacterNameCloseButtons.Clear();
            iCharacterCount = 0;
            do_CreateAddButton();
            do_RePositionAddButton();
        }
        
        #endregion

    }
}
